package MianCalPak;

import java.io.IOException;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import DB.DBProvider;

/**
 * Servlet implementation class Homeservlet
 */
public class Homeservlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Homeservlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		Integer AjaxHandel = (Integer)request.getSession().getAttribute("AjaxHandel");
		
		//special cases handling
		  if((AjaxHandel != null ) && (AjaxHandel == 1))
		  {
			  Integer Action = (Integer)request.getSession().getAttribute("Action");
			  request.getSession().setAttribute("AjaxHandel", 0);
			  
			  response.getWriter().write("<center>");
			  
			  if(Action == 0) //fail because of logic case
			  {
				  response.getWriter().write(" <br />");
				  response.getWriter().write("<br> <h1>Action Failed!! </h1>");
				  response.getWriter().write("<br> <img height=\"100\" width=\"100\" src=\"style/x.png\"  /> ");
				  response.getWriter().write(" <br />");
				  
				  String failcase = (String)request.getSession().getAttribute("CourseExist");
				  if ((failcase != null ) && (failcase.equals("yes")))
				  {
					  request.getSession().removeAttribute("CourseExist");
					  response.getWriter().write(" Course with that title exist already!! ");
					  response.getWriter().write(" <br />");
					  
				  }
				  
				  failcase = (String)request.getSession().getAttribute("CourseSessionOverlap");
				  if ((failcase != null ) && (failcase.equals("yes")))
				  {
					  request.getSession().removeAttribute("CourseSessionOverlap");
					  response.getWriter().write(" Sessions of the course you tried to add overleap!");
					  response.getWriter().write(" <br />");
					  
				  }
				  
				  failcase = (String)request.getSession().getAttribute("CourseHaveUser");
				  if ((failcase != null ) && (failcase.equals("yes")))
				  {
					  request.getSession().removeAttribute("CourseHaveUser");
					  response.getWriter().write(" Course already have users! you can't edit!");
					  response.getWriter().write(" <br />");
					  
				  }
				  
				  failcase = (String)request.getSession().getAttribute("CourseSessionOverlapGroup");
				  if ((failcase != null ) && (failcase.equals("yes")))
				  {
					  request.getSession().removeAttribute("CourseSessionOverlapGroup");
					  response.getWriter().write(" Sessions of the course you tried to add overleap other course from same group!");
					  response.getWriter().write(" <br />");
					  
				  }
		
				  response.getWriter().write(" please try again !");
				 
				  response.getWriter().write("</center>");
				  return;
			  }

			  if(Action == 1) // success case
			  {
				  
				  response.getWriter().write("<br> <h1>Action completed successfully!!</h1>");
				  response.getWriter().write("<br> <img height=\"100\" width=\"100\" src=\"style/Completed.jpg\"  /> ");
				  response.getWriter().write("</center>");
				  return;
			  }
			  
			  if(Action == 3) //Enternal error
			  {
				  response.getWriter().write(" <br />");
				  response.getWriter().write("<br> <h1>Internal server error! </h1>");
				  response.getWriter().write("<p>sorry it seems like we had and DB error, please login again</p>");
				  response.getWriter().write("<br> <img height=\"100\" width=\"100\" src=\"style/x.png\"  /> ");
				  response.getWriter().write("<a href=\"\">go back</a>");
				  response.getWriter().write(" <br />");
				  
			  }


			  response.getWriter().write("<br> <b>Unknown Action </b>");
			  response.getWriter().write("<br> <img height=\"100\" width=\"100\" src=\"style/x.png\"  /> ");
			  response.getWriter().write("</center>");
			  return;
			  
		  }
		
		
		  String op = request.getParameter("op");
		  if(op == null)
		  {
			  response.sendRedirect("index.jsp");
			  return;
		  }
		  if (op.toLowerCase().equals("home")){
			  response.sendRedirect("Web/home.jsp");
			  return;
		  }
		  if (op.toLowerCase().equals("logout")){
			  response.sendRedirect("Login");
			  return;
		  }
		  if (op.toLowerCase().equals("profile")){
			  
			  response.sendRedirect("Web/profile.jsp");
			  return;
		  }
		  
		  if (op.toLowerCase().equals("addcourse")){
			  response.sendRedirect("addcourse.jsp");
			  return;
		  }
		  
		  if (op.toLowerCase().equals("addcourseexe"))
		  {
			  
			  ExecuteAddCourse(request,response);
			  return;
		  }
		  

		  
		  if (op.toLowerCase().equals("addses")){
			  addsession(request,response);
			  return;
		  }
		  
		  if (op.toLowerCase().equals("courses")){
			  
			  response.sendRedirect("Web/courses.jsp");
			  return;
		  }
		  
		  if (op.toLowerCase().equals("coursespage")){
			  
			  String tt = request.getParameter("title");
			  response.sendRedirect("coursepage.jsp?title="+tt);
			  return;
		  }
		  if (op.toLowerCase().equals("registercourse")){
			  
			  RegCourse(request,response);
			  return;
		  }
		  if (op.toLowerCase().equals("coursesearch")){
			  
			  response.sendRedirect("Web/courseSearch.jsp");
			  return;
		  }
		  
		  if (op.toLowerCase().equals("users")){
			  
			  response.sendRedirect("Web/users.jsp");
			  return;
		  }
		  
		  if (op.toLowerCase().equals("timetable")){
			  
			  response.sendRedirect("Web/timeTable.jsp");
			  return;
		  }
		  
		  if (op.toLowerCase().equals("deluser"))
		  {
			  
			  delUser(request,response);
			  return;
		  }
		  
		  if (op.toLowerCase().equals("delcourse"))
		  {
			  
			  delCourse(request,response);
			  return;
		  }
		  
		  if (op.toLowerCase().equals("unregister"))
		  {
			  
			  Unregister(request,response);
			  return;
		  }
		  
		  if (op.toLowerCase().equals("about"))
		  {
			  
			  response.sendRedirect("about.html");
			  return;
		  }
		  
		  
		  
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	
	
	public  void ExecuteAddCourse(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		
		request.getSession().setAttribute("AjaxHandel", 1);
		request.getSession().setAttribute("Action", 0);
		
		 String admin = (String)request.getSession().getAttribute("administrator");

		 String title = request.getParameter("Coursetitle");
		 String description = request.getParameter("description");
		 String number_credit_points = request.getParameter("creditpoints"); 
		 String course_capacity = request.getParameter("capacity"); 
		 String group_number = request.getParameter("Group"); 
		 
		 String[] starts = request.getParameterValues("start");
		 String[] ends = request.getParameterValues("end");
		 
		 int[] istarts = new int[5];
		 int[] iends = new int[5];
		 int len = 0;
		
		//Check input - server side!
		
		if (null == title || 
			null == description || 
			null == number_credit_points ||
			null == course_capacity ||
			null == group_number ||
			title.length() > 50 || 
			description.length() > 1000 ||
			(starts.length==0) ||
			( ends.length==0) ||
			(starts.length != ends.length) ||
			!(number_credit_points.matches("[0-9]+"))||
			!(course_capacity.matches("[0-9]+"))||
			!(group_number.matches("[0-9]+"))){
			
				response.sendError(HttpServletResponse.SC_BAD_REQUEST);
				return;
			}
		
		//get the sessions as Integer
		for(int i=0 ; i < starts.length ; i ++)
		{
			if(!starts[i].equals(""))
			{	
				istarts[i] = Integer.parseInt(starts[i]);
				iends[i] = Integer.parseInt(ends[i]);
				
				if ((istarts[i] > 70) || (iends[i] > 70))
				{
					response.sendError(HttpServletResponse.SC_BAD_REQUEST);
					
				}
				
				len++;
			}
			
		}
		//cheack overleap for the sessions of the course
		for(int i=0 ; i < len ; i ++)
		{
			for(int j=i+1 ; j < len ; j ++)
			{
				
				if(( istarts[i] <= iends[j] && istarts[j] <= iends[i] ))
				{
					request.getSession().setAttribute("CourseSessionOverlap", "yes");
					response.sendRedirect("");
					return;
					
				}
				
				
			}
		}
		
		
			 int inumber_credit_points = Integer.parseInt(number_credit_points);
			 int icourse_capacity = Integer.parseInt(course_capacity);
			 int igroup_number = Integer.parseInt(group_number);
			
			Properties p = new Properties();
			p.load(getServletContext().getResourceAsStream("/WEB-INF/config"));
			
			
			//only admin can add courses
			if ((admin==null) ||!(admin.equals("true")))
			{
				
				response.sendError(HttpServletResponse.SC_BAD_REQUEST);
				return;
			}
			
			try {
				
				DBProvider provider = new DBProvider(p);
				
				//check if course exist
				ResultSet res = provider.courseDetails(title);
				
				if (res.next()){
					request.getSession().setAttribute("CourseExist", "yes");
					response.sendRedirect("");
					return;
				} 
				
				
				res =  provider.getGroupCourses(igroup_number);
				Set<String> GroupCourses = new	 HashSet<String>();
				
				//cheacking Overlap for all courses in Group
				if (res.next())
				{
					do
					{
						GroupCourses.add(res.getString("course_title"));
					}while (res.next());
						
				}
				res.close();
					
						for(String samegroupcourse : GroupCourses)
						{
							res = provider.getCourseSessions(samegroupcourse);
							while (res.next())
							{
								int tempstart = res.getInt("start_time_slot");
								int tempend = res.getInt("end_time_slot");
								
								for(int j=0 ; j < len ; j++)
								{
									
									if(( istarts[j] <= tempend && tempstart <= iends[j] ))
									{
										request.getSession().setAttribute("CourseSessionOverlapGroup", "yes");
										response.sendRedirect("");
										return;
										
									}
									
									
								}
													
							}
						}
				
				
				
				
				
				//add course
				provider.addCourse(title, description, inumber_credit_points, icourse_capacity, igroup_number);
				
				for(int i =0; i < len ; i++)
				{
					provider.addSession(title, istarts[i], iends[i]);
					
				}
			
				//goto index
				request.getSession().setAttribute("Action", 1);
				response.sendRedirect("");
			}		
			
			catch (Exception e) {
				
				
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				e.printStackTrace();
				
			} 
	
		
		
	}
	
	
	public static ArrayList<String> canRegister(DBProvider provider,String username,String title ,int cap, int group,int[] out_regusers)
	{
		
			Set<Integer> groups = new HashSet<Integer>();
			Set<String> userCourses = new	 HashSet<String>();
			ArrayList<String> reasons = new ArrayList<String>(); 
			ArrayList<Integer> course_starts = new ArrayList<Integer>();
			ArrayList<Integer> course_ends  = new ArrayList<Integer>();
		
		   if ( title == null || username == null )
		   {
			   return reasons; 
		   }
		   
		   try {
		   ResultSet res;
		   
			int capacity = cap;
			int group_number =  group;

			
			
			boolean canReg = true;
			
			res = provider.getNumberOfRegCourseUsers(title);
			 if (!res.next())
			 {
				   return reasons;
			 }
			
			 int registeredUsers = res.getInt(1);
			 
			 out_regusers[0] = registeredUsers;
				
				
			 if(capacity<(registeredUsers+1))
			 {
				  canReg = false;
				  reasons.add("Course is full");
				 
			 }
			 
			 
			 res = provider.getCoursesUser(username);
			 if (res.next())
			 {
				 res.beforeFirst();
				 while (res.next())
				{
					 groups.add(res.getInt("group_number"));
					 userCourses.add(res.getString("course_title"));
				}
				 
				 if(userCourses.contains(title))
				 {
					 
					canReg = false;
					reasons.add("Already registered");
			
					 
				 }
				 
				 if(!groups.contains(group_number))
				 {
					 if((groups.size()+1)> 3)
					 {
						 canReg = false;
						 reasons.add("Can't register to more than 3 different groups");
						 
					 }
					 
				 }
				 
			 }
			 
			 if(canReg)
			 {
			
				 res = provider.getCourseSessions(title); 
				 int k =0;
				 while (res.next())
				 {
					 course_starts.add(k,res.getInt("start_time_slot"));
					 course_ends.add(k,res.getInt("end_time_slot"));
					 k++;
				 } 
				 res.close();
				 
				 
				 for(String usercourse : userCourses)
					{
						res = provider.getCourseSessions(usercourse);
						while (res.next())
						{
							int tempstart = res.getInt("start_time_slot");
							int tempend = res.getInt("end_time_slot");
							
							for(int j=0 ; j < course_starts.size() ; j++)
							{
								
								if(( course_starts.get(j) <= tempend && tempstart <= course_ends.get(j) ))
								{
									canReg = false;
								    reasons.add("Can't register because course overleap with other course you have");
								    return reasons;
								}
								
							}					
						}
					}
			 }
	
		   }
		   catch (Exception e) {
				
				
			   reasons.add("DB error");
				
			   return reasons;
			} 
		return reasons;
	}
	
	
	
	public  void RegCourse(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		
		request.getSession().setAttribute("AjaxHandel", 1);
		request.getSession().setAttribute("Action", 0);
		
		String user = (String)request.getSession().getAttribute("username");
		String title = request.getParameter("title");
		
		//Check input - server side!
		
		if (null == title || user == null )
		{
			
				response.sendError(HttpServletResponse.SC_BAD_REQUEST);
				return;
		}
		Properties p = new Properties();
		p.load(getServletContext().getResourceAsStream("/WEB-INF/config"));

	    try {
				
				DBProvider provider = new DBProvider(p);
				
				//Register user
				 provider.courseRegister(user,title);
				
				//goto index
				request.getSession().setAttribute("Action", 1);
				response.sendRedirect("");
			}		
			
			catch (Exception e) {
				
				request.getSession().setAttribute("Action", 0);
				response.sendRedirect("");
				e.printStackTrace();
				
			} 
	
		
		
	}
	
	public  void addsession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		
		request.getSession().setAttribute("AjaxHandel", 1);
		request.getSession().setAttribute("Action", 0);
		
		String user = (String)request.getSession().getAttribute("username");
		String title = request.getParameter("title");
		String start = request.getParameter("start");
		String end = request.getParameter("end");
		
		ArrayList<Integer> course_starts = new ArrayList<Integer>();
		ArrayList<Integer> course_ends  = new ArrayList<Integer>();
		
		//Check input - server side!
		
		if (null == title || user == null ||start ==null || end == null )
		{
	
				response.sendError(HttpServletResponse.SC_BAD_REQUEST);
				return;
		}
		
		int istart =Integer.parseInt(start);
		int iend = Integer.parseInt(end);
		
		
		Properties p = new Properties();
		p.load(getServletContext().getResourceAsStream("/WEB-INF/config"));

	    try {
				
				DBProvider provider = new DBProvider(p);
				//cheack overleap for the sessions of the course
				 ResultSet res;
				 
				 res = provider.getNumberOfRegCourseUsers(title);
				 if (!res.next())
				 {
					 response.sendError(HttpServletResponse.SC_BAD_REQUEST);
					 return;
				 }
				
				 int registeredUsers = res.getInt(1);
				 if(registeredUsers != 0)
				 {
					 
					request.getSession().setAttribute("CourseHaveUser", "yes");
					response.sendRedirect("");
					return;
					 
					 
				 }
				 
				 res = provider.getCourseSessions(title); 
				 int k =0;
				 while (res.next())
				 {
					 course_starts.add(k,res.getInt("start_time_slot"));
					 course_ends.add(k,res.getInt("end_time_slot"));
					 k++;
				 } 
				 res.close();
					
				for(int j=0 ; j < course_starts.size() ; j++)
				{
						
						if(( course_starts.get(j) <= iend && istart <= course_ends.get(j) ))
						{
							request.getSession().setAttribute("CourseSessionOverlap", "yes");
							response.sendRedirect("");
							return;
						}
						
				}
				
				//Register user
				provider.addSession(title, istart,iend);
				
				//goto index
				request.getSession().setAttribute("Action", 1);
				response.sendRedirect("");
			}		
			
			catch (Exception e) 
			{
				
				request.getSession().setAttribute("Action", 0);
				response.sendRedirect("");
				e.printStackTrace();
				
			} 
	
		
		
	}
	
	
	public  void delUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		
		String duser = request.getParameter("user");
		String num = request.getParameter("number");
		String admin = (String)request.getSession().getAttribute("administrator");
		
		
		if(admin == null || duser == null || num == null || !admin.equals("true"))
		{
			throw new ServletException();
		}
		
		
		
		Properties p = new Properties();
		p.load(getServletContext().getResourceAsStream("/WEB-INF/config"));

	    try {
				
				 DBProvider provider = new DBProvider(p);
				 provider.deleteUser(duser);
				 response.sendRedirect("/Calendars/Web/users.jsp?number="+num);
				 
			
			}		
			
			catch (Exception e) 
			{
				
				response.sendError(HttpServletResponse.SC_BAD_REQUEST);
				e.printStackTrace();
				return;
				
			} 
		
	}
	
	public  void Unregister(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		request.getSession().setAttribute("AjaxHandel", 1);
		request.getSession().setAttribute("Action", 0);
		String title = request.getParameter("title");
		String user = (String)request.getSession().getAttribute("username");
		
		
		
		Properties p = new Properties();
		p.load(getServletContext().getResourceAsStream("/WEB-INF/config"));

	    try {
				
				 DBProvider provider = new DBProvider(p);
				 provider.deletereg(user, title);
				 request.getSession().setAttribute("Action", 1);
				 response.sendRedirect("");
				 
			
			}		
			
			catch (Exception e) 
			{
				
				response.sendRedirect("");
				e.printStackTrace();
				return;
				
			} 
		
	}
	
	
	
	
	public  void delCourse(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		
		request.getSession().setAttribute("AjaxHandel", 1);
		request.getSession().setAttribute("Action", 0);
		
		String title = request.getParameter("title");
		String admin = (String)request.getSession().getAttribute("administrator");
		
		
		if( admin == null || title == null  || !admin.equals("true") )
		{
			response.sendRedirect("");
			return;
		}
		
		
		Properties p = new Properties();
		p.load(getServletContext().getResourceAsStream("/WEB-INF/config"));

	    try {
				
				 DBProvider provider = new DBProvider(p);
				 provider.deleteCourse(title);
				 request.getSession().setAttribute("Action", 1);
				 response.sendRedirect("");
				 
			
			}		
			
			catch (Exception e) 
			{
				
				request.getSession().setAttribute("Action", 0);
				response.sendRedirect("");
				e.printStackTrace();
				return;
				
			} 
			
		
		
	}
	
	
	
}
